package com.ly.nethub.task

import com.ly.nethub.interf.TaskSendListener
import kotlinx.coroutines.CompletableDeferred
import java.util.concurrent.atomic.AtomicLong

/**
 * 任务，比如心跳任务，请求任务，认证任务之类的
 */
abstract class BaseTask(val isHeartbeat: Boolean = false) : Comparable<BaseTask> {

    //任务Id,全局唯一，自增
    @Suppress("MemberVisibilityCanBePrivate")
    open val taskId: Long = globalTaskId.getAndIncrement()

    internal var deferred = CompletableDeferred<Any?>()

    /**
     * 当前重发次数
     */
    internal var retryCount = 0
        private set

    /**
     * 结果回调
     */
    var callback: TaskSendListener? = null

    /**
     * 任务优先级
     */
    protected open val priority: Int = 1

    /**
     * 是否允许重发,如果允许，低可能性会出现超时时间可能会是timeout*n ms
     */
    open val isAllowResend: Boolean = true

    /**
     * 任务超时时间 ms
     */
    open val timeout get() = 15 * 1000L

    /**
     * 构建请求体，例如这里做构建json或者protobuf
     * @return 根据需求返回json或者protobuf
     */
    abstract fun buildRequest(): Any

    /**
     * 是否是这个task对应的响应消息，例如通过taskId是否一致来判断，如果不需要这个msg，返回null
     * @return 返回值将会为[TaskSendListener.onTaskSuccess]的入参
     */
    abstract fun isValidResponse(msg: Any?): Any?

    /**
     * 重试次数
     */
    internal fun increaseRetryCount() {
        //增加
        retryCount += 1
    }

    /**
     * 重置deferred
     * deferred将作为挂起工具，作为超时计时挂起工具
     */
    internal fun tryInitialDeferred() {
        if (deferred.isCompleted) {
            deferred = CompletableDeferred()
        }
    }


    override fun compareTo(other: BaseTask): Int {
        val priorityCompare = priority.compareTo(other.priority)
        if (priorityCompare != 0) {
            return priorityCompare
        }
        return taskId.compareTo(other.taskId)
    }

    companion object {
        val globalTaskId = AtomicLong(1)
    }
}